package thread;

import java.util.PriorityQueue;

class Mytimetask implements Comparable<Mytimetask>{

    private Runnable runnable;
    private long time;
    public Mytimetask(Runnable runnable,long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;
    }
    public void run(){
        runnable.run();
    }
    public long getTime(){
        return this.time;
    }

    @Override
    public int compareTo(Mytimetask o) {
        return (int)(this.time-o.time);
    }
}
class MyTimer{
    private Thread t=null;
    private PriorityQueue<Mytimetask>queue=new PriorityQueue<>();
    private Object locker1=new Object();
    public void schedule(Runnable runnable,long delay){
        synchronized (locker1) {
            Mytimetask task = new Mytimetask(runnable, delay);
            queue.offer(task);
            locker1.notify();
        }

    }
    public void cancel(){
        t.interrupt();
    }
    public MyTimer(){
        this.t=new Thread(()->{
           while(!Thread.currentThread().isInterrupted()){
               synchronized (locker1) {
                   try {
                       while(queue.isEmpty()) {
                           locker1.wait();
                           continue;//等到队列不为空再去执行
                       }
                       Mytimetask task = queue.peek();
                       if (task.getTime() <= System.currentTimeMillis()) {
                           queue.poll();
                           task.run();
                       } else {
                            locker1.wait(task.getTime()-System.currentTimeMillis());
                       }
                   }
                   catch (InterruptedException e){
                       break;
                   }
               }
           }
        });
        t.start();
    }

}

public class ThreadDemo28 {
    public static void main(String[] args) throws InterruptedException {
        MyTimer timer=new MyTimer();
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        },3000);
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        },2000);
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        },1000);
        Thread.sleep(5000);
        timer.cancel();
    }
}
